home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 10 / FM Towns Free Software Collection 10.iso / ms_dos / tool / fwcp / src / main.c < prev    next >
Text File  |  1995-04-04  |  32KB  |  1,573 lines

  1. /***************
  2.           1         2         3         4         5         6         7
  3. 01234567890123456789012345678901234567890123456789012345678901234567890123456789+--------------------------------------+--------------------------------------+
  4. |A:\ABC\DEF\GHI                        |F:\T_OS                               |
  5. |DIR 12345 / FILE 12345 SIZE 123456789 |                                      |
  6. +--------------------------------------+--------------------------------------+
  7. |12345678.123 12345678 94/10/25 11:15 *|12345678.123 12345678 94/10/25 11:15 *|
  8. |12345678.123    <DIR> 94/10/25 11:15 *|                                      |
  9. |                                      |                                      |
  10. |                                      |                                      |
  11. |                                      |                                      |
  12. |                                      |                                      |
  13. +--------------------------------------+--------------------------------------+
  14. 01234567890123456789012345678901234567890123456789012345678901234567890123456789****************/
  15. #include    <stdio.h>
  16. #include    <stdlib.h>
  17. #include    <stdarg.h>
  18. #include    <string.h>
  19. #include    <malloc.h>
  20. #include    <direct.h>
  21. #include    "defs.h"
  22. #include    "dir.h"
  23. #include    "key.h"
  24.  
  25. #define    VERSION    "FWCP version 0.02 1995.03.03 Nanno-NET(Ken)"
  26.  
  27.     char    *config_file  = "\\lib\\fwcp.def";
  28.     char    *termcap_file = NULL;
  29.     char    *term_name    = NULL;
  30.  
  31. typedef    struct    {
  32.     int    drv;
  33.     DIR    *dir;
  34.     int    top, otop;
  35.     int    pos, opos;
  36.     int    max;
  37.     int    que;
  38.     int    mode, stat;
  39.     char    cwd[128];
  40. } WIND;
  41.  
  42. static    WIND    wind_buf[2];
  43. static    int    dir_menu_ent = 0;
  44. static    int    dir_menu_max = 0;
  45. static    char    **dir_menu_vct;
  46.  
  47. static    int        scale_pos = 0;
  48. static    unsigned long    scale_total = 0;
  49. static    unsigned long    scale_size = 0;
  50.  
  51. #define    HISDIRMAX    16
  52. static    char    *chdir_vct[HISDIRMAX + 1];
  53.  
  54.     char    *stralloc(char *str);
  55.     unsigned long dir_size(char *dir);
  56.  
  57. char    *strform(char *tmp, char *str, int max)
  58. {
  59.     int n, i;
  60.     char *p;
  61.  
  62.     if ( strlen(str) < max )
  63.     return strcpy(tmp, str);
  64.  
  65.     p = tmp;
  66.     for ( n = 0 ; n < 3 ; ) {
  67.     if ( iskan(str) ) {
  68.         *(p++) = *(str++);
  69.         *(p++) = *(str++);
  70.         n += 2;
  71.     } else {
  72.         *(p++) = *(str++);
  73.         n += 1;
  74.     }
  75.     }
  76.  
  77.     *(p++) = '.';
  78.     *(p++) = '.';
  79.     *(p++) = '.';
  80.     n += 3;
  81.  
  82.     i = strlen(str) - (max - n);
  83.     while ( i > 0 ) {
  84.     if ( iskan(str) ) {
  85.         str += 2;
  86.         i -= 2;
  87.     } else {
  88.         str += 1;
  89.         i -= 1;
  90.     }
  91.     }
  92.  
  93.     while ( *str != '\0' )
  94.     *(p++) = *(str++);
  95.     *p = '\0';
  96.  
  97.     return tmp;
  98. }
  99. void    message(char *form, ...)
  100. {
  101.     int n;
  102.     int len;
  103.     int line = 1;
  104.     int sx, sy;
  105.     char *p, *s;
  106.     va_list arg;
  107.     char tmp[BUFSIZ];
  108.  
  109.     va_start(arg, form);
  110.     vsprintf(tmp, form, arg);
  111.     va_end(arg);
  112.  
  113.     n = len = 0;
  114.     for ( p = tmp ; *p != '\0' ; ) {
  115.     if ( *p == '\n' ) {
  116.         *(p++) = '\0';
  117.         line++;
  118.         n = 0;
  119.     } else if ( iskanji(p[0]) && iskanji(p[1]) ){
  120.         n += 2;
  121.         p += 2;
  122.     } else {
  123.         n++;
  124.         p++;
  125.     }
  126.  
  127.     if ( n > len )
  128.         len = n;
  129.  
  130.     if ( n >= 70 ) {
  131.         for ( s = p ; *s != '\0' ; s++ )
  132.         ;
  133.         while ( s >= p ) {
  134.         *(s + 1) = *s;
  135.         s--;
  136.         }
  137.         *(p++) = '\0';
  138.         line++;
  139.         n = 0;
  140.     }
  141.     }
  142.  
  143.     sx = (SCR_X - len) / 2;
  144.     sy = (SCR_Y - line) / 2;
  145.  
  146.     SAVESCREEN();
  147.     CUROFF();
  148.     ERRCOL();
  149.     BLINKCOL();
  150.     wind(sx - 1, sy, len + 2, line);
  151.     NOMCOL();
  152.     p = tmp;
  153.     for ( n = 0 ; n < line ; n++ ) {
  154.     LOCATE(sx, sy + n);
  155.     PUTS(p);
  156.     while ( *(p++) != '\0' )
  157.         ;
  158.     }
  159.     STDCOL();
  160.     BEEP();
  161.     FLUSH();
  162.  
  163.     while ( KBHIT() )
  164.     GETCH();
  165.  
  166.     GETCH();
  167.  
  168.     LOADSCREEN();
  169.     LOCATE(0, SCR_Y - 1);
  170.     CURON();
  171.     FLUSH();
  172. }
  173. void    scale(unsigned long sz)
  174. {
  175.     int n;    
  176.     static char scl_char[]={ 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x87 };
  177.  
  178.     if ( scale_total <= 0 )
  179.     return;
  180.  
  181.     scale_size += sz;
  182.     if ( scale_size >= 0x000FFFFFL )
  183.     n = scale_size / (scale_total / 320L);
  184.     else
  185.     n = scale_size * 320L / scale_total;
  186.  
  187.     if ( scale_pos > n ) {
  188.     LOCATE(20, 14);
  189.     REPCHR(' ', 40);
  190.     scale_pos = 0;
  191.     }
  192.  
  193.     while ( scale_pos < n ) {
  194.     LOCATE(20 + (scale_pos / 8), 14);
  195.     PUTANK(scl_char[scale_pos % 8]);
  196.     scale_pos++;
  197.     }
  198.  
  199.     LOCATE(38, 12);
  200.     if ( scale_size >= 0x00FFFFFFL )
  201.     n = scale_size / (scale_total / 100L);
  202.     else
  203.     n = scale_size * 100L / scale_total;
  204.     FPUTS("%3d%%", n);
  205.     FLUSH();
  206. }
  207. void    init_scale(unsigned long sz)
  208. {
  209.     scale_total = sz;
  210.     scale_pos = 0;
  211.     scale_size = 0;
  212.     CUROFF();
  213.     SAVESCREEN();
  214.     wind(20, 12, 40, 3);
  215.     FLUSH();
  216. }
  217. void    apend_scale(unsigned long sz)
  218. {
  219.     scale_total += sz;
  220.     scale(0);
  221. }
  222. void    finis_scale()
  223. {
  224.     scale_total = 0;
  225.     LOADSCREEN();
  226.     BEEP();
  227.     LOCATE(0, SCR_Y - 1);
  228.     CURON();
  229.     FLUSH();
  230. }
  231. int    abort_check()
  232. {
  233.     int ch;
  234.  
  235.     if ( KBHIT() == 0 )
  236.     return FALSE;
  237.     ch = GETCH();
  238.     switch(ch) {
  239.     case K_ABORT:
  240.     case K_END_OF:
  241.     message("Copy Abort...");
  242.     return ERR;
  243.     }
  244.     return FALSE;
  245. }
  246. void    verbose(char *form, ...)
  247. {
  248.     int n;
  249.     va_list arg;
  250.     char    tmp[128];
  251.  
  252.     va_start(arg, form);
  253.     vsprintf(tmp, form, arg);
  254.     va_end(arg);
  255.  
  256.     if ( strlen(tmp) > 78 )
  257.     tmp[78] = '\0';
  258.  
  259.     SAVECUR();
  260.     LOCATE(1, SCR_Y - 2);
  261.     PUTS(tmp);
  262.     REPCHR(' ', 77 - strlen(tmp));
  263.     LOADCUR();
  264.     FLUSH();
  265. }
  266. static    char    *file_name(char *name)
  267. {
  268.     int n = 0;
  269.     static char tmp[16];
  270.  
  271.     if ( *name != '.' ) {
  272.     while ( n < 8 && *name != '.' )
  273.         tmp[n++] = *(name++);
  274.     while ( n < 8 )
  275.         tmp[n++] = ' ';
  276.     }
  277.     while ( n < 12 && *name != '\0' )
  278.     tmp[n++] = *(name++);
  279.     while ( n < 12 )
  280.     tmp[n++] = ' ';
  281.     tmp[n] = '\0';
  282.     return tmp;
  283. }
  284. static    char    *file_time(int date, int time)
  285. {
  286.     static char tmp[24];
  287.  
  288.     sprintf(tmp, "%02d-%02d-%02d %02d:%02d",
  289.                 (((date >> 9) & 0x7F) + 80) % 100,
  290.                 (date >> 5) & 0x0F,
  291.                 date & 0x1F,
  292.                 (time >> 11) & 0x1F,
  293.                 (time >> 5) & 0x3F,
  294.                 time & 0x1F);
  295.     return tmp;
  296. }
  297. static    int    file_check(char *p)
  298. {
  299.     while ( *p != '\n' && *p != '\0' ) {
  300.         if ( !isdigit(*p) && !isalpha(*p) &&
  301.                 *p != '\\' && *p != '.' && *p != '_' )
  302.             return ERR;
  303.         p++;
  304.     }
  305.     return FALSE;
  306. }
  307. static    void    disp_attr(int mode)
  308. {
  309.     switch(mode) {
  310.     case 0:        /* file name */
  311.     MSGCOL();
  312.     ATTSET(12);
  313.     ACTCOL();
  314.     ATTSET(26);
  315.     break;
  316.     case 1:        /* sub name */
  317.     ACTCOL();
  318.     ATTSET(8);
  319.     MSGCOL();
  320.     ATTSET(4);
  321.     ACTCOL();
  322.     ATTSET(26);
  323.     break;
  324.     case 2:        /* size */
  325.     ACTCOL();
  326.     ATTSET(13);
  327.     MSGCOL();
  328.     ATTSET(8);
  329.     ACTCOL();
  330.     ATTSET(17);
  331.     break;
  332.     case 3:        /* date & time */
  333.     ACTCOL();
  334.     ATTSET(22);
  335.     MSGCOL();
  336.     ATTSET(14);
  337.     ACTCOL();
  338.     ATTSET(2);
  339.     break;
  340.     }
  341. }
  342. static    void    disp_wind(int no)
  343. {
  344.     int n, x;
  345.     int rc = FALSE;
  346.     WIND *wp;
  347.     DIRECT *dp;
  348.     int dc = 0;
  349.     int fc = 0;
  350.     long sz = 0;
  351.     char tmp[40];
  352.  
  353.     wp = &(wind_buf[no]);
  354.     x = (no == 0 ? 1 : 40);
  355.  
  356.     if ( wp->dir == NULL )
  357.     sprintf(tmp, "%c:", wp->drv + 'A' - 1);
  358.     else
  359.     strform(tmp, wp->cwd, 38);
  360.  
  361.     SAVECUR();
  362.     LOCATE(x, 1);
  363.     FPUTS("%-38.38s", tmp);
  364.  
  365.     if ( wp->dir == NULL ) {
  366.     LOCATE(x, 2);
  367.     PUTS("DIR ----- / FILE ----- SIZE --------- ");
  368.  
  369.     for ( n = 4 ; n < (SCR_Y - 3) ; n++ ) {
  370.         LOCATE(x, n);
  371.         REPCHR(' ', 38);
  372.     }
  373.  
  374.     } else {
  375.     seekdir(wp->dir, 0);
  376.     while ( (dp = readdir(wp->dir)) != NULL ) {
  377.         if ( IS_DIR(dp) )
  378.         dc++;
  379.         else {
  380.         fc++;
  381.         sz += dp->d_size;
  382.         }
  383.     }
  384.     LOCATE(x, 2);
  385.     FPUTS("DIR %5d / FILE %5d SIZE %9ld ", dc, fc, sz);
  386.  
  387.     seekdir(wp->dir, wp->top);
  388.     for ( n = 4 ; n < (SCR_Y - 3) ; n++ ) {
  389.         LOCATE(x, n);
  390.         if ( (dp = readdir(wp->dir)) == NULL )
  391.         REPCHR(' ', 38);
  392.         else {
  393.         if ( dp->d_mark )
  394.             ACTCOL();
  395.  
  396.         FPUTS("%-12.12s ", file_name(dp->d_name));
  397.         if ( IS_DIR(dp) )
  398.             PUTS("   <DIR> ");
  399.         else
  400.             FPUTS("%8ld ", dp->d_size);
  401.         FPUTS("%s ", file_time(dp->d_date, dp->d_time));
  402.         FPUTS("%c", file_check(dp->d_name) ? '*':' ');
  403.  
  404.         if ( wp->pos == (n - 4) ) {
  405.             LOCATE(x, n);
  406.             if ( dp->d_mark )
  407.             BOLDCOL();
  408.             REVCOL();
  409.             disp_attr(wp->mode);
  410.         }
  411.  
  412.         STDCOL();
  413.         NOMCOL();
  414.         }
  415.     }
  416.  
  417.     wp->opos = wp->pos;
  418.     wp->otop = wp->top;
  419.     }
  420.  
  421.     LOADCUR();
  422.     FLUSH();
  423. }
  424. static    void    update_wind(int no)
  425. {
  426.     int n, x;
  427.     WIND *wp;
  428.     DIRECT *dp;
  429.  
  430.     wp = &(wind_buf[no]);
  431.     x = (no == 0 ? 1 : 40);
  432.  
  433.     if ( wp->otop != wp->top ) {
  434.     seekdir(wp->dir, wp->top);
  435.     for ( n = 4 ; n < (SCR_Y - 3) ; n++ ) {
  436.         LOCATE(x, n);
  437.         if ( (dp = readdir(wp->dir)) == NULL )
  438.         REPCHR(' ', 38);
  439.         else {
  440.         if ( dp->d_mark )
  441.             ACTCOL();
  442.  
  443.         FPUTS("%-12.12s ", file_name(dp->d_name));
  444.         if ( IS_DIR(dp) )
  445.             PUTS("   <DIR> ");
  446.         else
  447.             FPUTS("%8ld ", dp->d_size);
  448.         FPUTS("%s ", file_time(dp->d_date, dp->d_time));
  449.         FPUTS("%c", file_check(dp->d_name) ? '*':' ');
  450.  
  451.         if ( wp->pos == (n - 4) ) {
  452.             LOCATE(x, n);
  453.             if ( dp->d_mark )
  454.             BOLDCOL();
  455.             REVCOL();
  456.             disp_attr(wp->mode);
  457.         }
  458.  
  459.         STDCOL();
  460.         NOMCOL();
  461.         }
  462.     }
  463.  
  464.     } else if ( wp->opos != wp->pos ) {
  465.     if ( wp->opos >= 0 ) {
  466.         seekdir(wp->dir, wp->top + wp->opos);
  467.         if ( (dp = readdir(wp->dir)) != NULL && dp->d_mark )
  468.         ACTCOL();
  469.         LOCATE(x, 4 + wp->opos);
  470.         ATTSET(38);
  471.         STDCOL();
  472.     }
  473.     if ( wp->pos >= 0 ) {
  474.         seekdir(wp->dir, wp->top + wp->pos);
  475.         if ( (dp = readdir(wp->dir)) != NULL && dp->d_mark )
  476.         BOLDCOL();
  477.         REVCOL();
  478.         LOCATE(x, 4 + wp->pos);
  479.         disp_attr(wp->mode);
  480.         NOMCOL();
  481.         STDCOL();
  482.     }
  483.     }
  484.  
  485.     wp->opos = wp->pos;
  486.     wp->otop = wp->top;
  487. }
  488. static    void    select_wind(int no)
  489. {
  490.     int n, x;
  491.  
  492.     x = (no == 0 ? 39 : 0);
  493.     LOCATE( 0 + x, 0); ATTSET(40);
  494.     LOCATE( 0 + x, 1); ATTSET(1); LOCATE(39 + x, 1); ATTSET(1);
  495.     LOCATE( 0 + x, 2); ATTSET(1); LOCATE(39 + x, 2); ATTSET(1);
  496.     LOCATE( 0 + x, 3); ATTSET(40);
  497.     for ( n = 4 ; n < (SCR_Y - 3) ; n++ ) {
  498.     LOCATE( 0 + x, n); ATTSET(1);
  499.     LOCATE(39 + x, n); ATTSET(1);
  500.     }
  501.     LOCATE( 0 + x, SCR_Y - 3); ATTSET(40);
  502.  
  503.     x = (no == 0 ? 0 : 39);
  504.     REVCOL();
  505.     LOCATE( 0 + x, 0); ATTSET(40);
  506.     LOCATE( 0 + x, 1); ATTSET(1); LOCATE(39 + x, 1); ATTSET(1);
  507.     LOCATE( 0 + x, 2); ATTSET(1); LOCATE(39 + x, 2); ATTSET(1);
  508.     LOCATE( 0 + x, 3); ATTSET(40);
  509.     for ( n = 4 ; n < (SCR_Y - 3) ; n++ ) {
  510.     LOCATE( 0 + x, n); ATTSET(1);
  511.     LOCATE(39 + x, n); ATTSET(1);
  512.     }
  513.     LOCATE( 0 + x, SCR_Y - 3); ATTSET(40);
  514.     NOMCOL();
  515.  
  516.     FLUSH();
  517. }
  518. void    screen_init(int no)
  519. {
  520.     int n;
  521.  
  522.     LOCATE(0, 0); PUTANK(0x9C); REPCHR(0x95, 38);
  523.     PUTANK(0x91); REPCHR(0x95, 38); PUTANK(0x9D);
  524.  
  525.     LOCATE(0, 1); PUTANK(0x96); REPCHR(0x20, 38);
  526.     PUTANK(0x96); REPCHR(0x20, 38); PUTANK(0x96);
  527.  
  528.     LOCATE(0, 2); PUTANK(0x96); REPCHR(0x20, 38);
  529.     PUTANK(0x96); REPCHR(0x20, 38); PUTANK(0x96);
  530.  
  531.     LOCATE(0, 3); PUTANK(0x93); REPCHR(0x95, 38);
  532.     PUTANK(0x8F); REPCHR(0x95, 38); PUTANK(0x92);
  533.  
  534.     for ( n = 4 ; n < (SCR_Y - 3) ; n++ ) {
  535.     LOCATE(0, n); PUTANK(0x96); REPCHR(0x20, 38);
  536.     PUTANK(0x96); REPCHR(0x20, 38); PUTANK(0x96);
  537.     }
  538.  
  539. #if 0
  540.     LOCATE(0, SCR_Y - 3); PUTANK(0x9E); REPCHR(0x95, 38);
  541.     PUTANK(0x90); REPCHR(0x95, 38); PUTANK(0x9F);
  542.  
  543.     LOCATE(0, SCR_Y - 2); ERALINE();
  544.     LOCATE(0, SCR_Y - 1); ERALINE();
  545. #else
  546.     LOCATE(0, SCR_Y - 3); PUTANK(0x93); REPCHR(0x95, 38);
  547.     PUTANK(0x90); REPCHR(0x95, 38); PUTANK(0x92);
  548.  
  549.     LOCATE(0, SCR_Y - 2); PUTANK(0x96);
  550.     REPCHR(0x20, 77); PUTANK(0x96);
  551.  
  552.     LOCATE(0, SCR_Y - 1); PUTANK(0x9E);
  553.     REPCHR(0x95, 77); PUTANK(0x9F);
  554. #endif
  555.  
  556.     select_wind(no);
  557. }
  558. int    chcwdrv(int drv)
  559. {
  560.     if ( _chdrive(drv) ) {
  561.     message("chdrive %c: %s", drv - 1 + 'A', strerror(errno));
  562.     return ERR;
  563.     }
  564.     return FALSE;
  565. }
  566. int    chcwdir(char *dir)
  567. {
  568.     if ( chdir(dir) ) {
  569.     message("chdir %s %s", dir, strerror(errno));
  570.     return ERR;
  571.     }
  572.     return FALSE;
  573. }
  574. int    exec_wind(int no)
  575. {
  576.     WIND *wp;
  577.     DIRECT *dp;
  578.  
  579.     wp = &(wind_buf[no]);
  580.  
  581.     seekdir(wp->dir, wp->top + wp->pos);
  582.     if ( (dp = readdir(wp->dir)) == NULL )
  583.     return ERR;
  584.  
  585.     if ( IS_DIR(dp) ) {
  586.     if ( chcwdir(dp->d_name) )
  587.         return ERR;
  588.     return TRUE;
  589.     } else {
  590.     if ( more(dp->d_name) )
  591.         return ERR;
  592.     return FALSE;
  593.     }
  594. }
  595. int    mark_wind(int no, int mode)
  596. {
  597.     WIND *wp;
  598.     DIRECT *dp;
  599.  
  600.     wp = &(wind_buf[no]);
  601.     if ( wp->dir == NULL || wp->pos < 0 )
  602.     return ERR;
  603.  
  604.     seekdir(wp->dir, wp->top + wp->pos);
  605.     if ( (dp = readdir(wp->dir)) == NULL || root_check(dp->d_name) )
  606.     return ERR;
  607.  
  608.     switch(mode) {
  609.     case ERR:
  610.     dp->d_mark = (dp->d_mark == TRUE ? FALSE : TRUE);
  611.     break;
  612.     case FALSE:
  613.     dp->d_mark = FALSE;
  614.     break;
  615.     case TRUE:
  616.     dp->d_mark = TRUE;
  617.     break;
  618.     }
  619.  
  620.     return FALSE;
  621. }
  622. int    all_mark_wind(int no)
  623. {
  624.     WIND *wp;
  625.     DIRECT *dp;
  626.  
  627.     wp = &(wind_buf[no]);
  628.     if ( wp->dir == NULL )
  629.     return ERR;
  630.  
  631.     seekdir(wp->dir, 0);
  632.     while ( (dp = readdir(wp->dir)) != NULL ) {
  633.     if ( root_check(dp->d_name) )
  634.         continue;
  635.     dp->d_mark = TRUE;
  636.     }
  637.     return FALSE;
  638. }
  639. int    skip_wind(int no)
  640. {
  641.     int n;
  642.     WIND *wp;
  643.     DIRECT *dp;
  644.  
  645.     wp = &(wind_buf[no]);
  646.     if ( wp->dir == NULL )
  647.     return ERR;
  648.  
  649.     n = (wp->pos < 0 ? 0 : (wp->top + wp->pos + 1));
  650.     seekdir(wp->dir, n);
  651.     while ( (dp = readdir(wp->dir)) != NULL ) {
  652.     if ( wild_mach("*.GGG", dp->d_name) ||
  653.          wild_mach("*.RRR", dp->d_name) ||
  654.          wild_mach("*.BAK", dp->d_name) ||
  655.          wild_mach("*.DOC", dp->d_name) ) {
  656.         if ( (wp->pos = (n - wp->top)) > (SCR_Y - 8) ) {
  657.         wp->pos = (SCR_Y - 8);
  658.         wp->top = n - (SCR_Y - 8);
  659.         }
  660.         break;
  661.     }
  662.     n++;
  663.     }
  664.     return FALSE;
  665. }
  666. int    open_wind(int no)
  667. {
  668.     int n, i;
  669.     WIND *wp;
  670.     DIR  *dir = NULL;
  671.     int  max = 0;
  672.     char *p;
  673.     char tmp[128];
  674.     DIRECT *dp, *np;
  675.  
  676.     wp = &(wind_buf[no]);
  677.  
  678.     if ( wp->dir != NULL ) {
  679.     max = wp->max;
  680.     strcpy(tmp, wp->cwd);
  681.     dir = wp->dir;
  682.     wp->dir = NULL;
  683.     }
  684.  
  685.     if ( chcwdrv(wp->drv) ||
  686.      getcwd(wp->cwd, 127) == NULL ||
  687.      (wp->dir = opendir(wp->cwd, wp->mode)) == NULL ) {
  688.     if ( dir != NULL )
  689.         closedir(dir);
  690.     return ERR;
  691.     }
  692.  
  693.     for ( n = 0 ; chdir_vct[n] != NULL && n < HISDIRMAX ; n++ ) {
  694.     if ( strcmp(chdir_vct[n], wp->cwd) == 0 ) {
  695.         p = chdir_vct[n];
  696.         for ( i = n ; i > 0 ; i-- )
  697.         chdir_vct[i] = chdir_vct[i - 1];
  698.         chdir_vct[i] = p;
  699.         n = i;
  700.         break;
  701.     }
  702.     }
  703.     if ( chdir_vct[n] == NULL ) {
  704.     if ( chdir_vct[HISDIRMAX - 1] != NULL )
  705.         free(chdir_vct[HISDIRMAX - 1]);
  706.     for ( n = (HISDIRMAX - 1) ; n > 0 ; n-- )
  707.         chdir_vct[n] = chdir_vct[n - 1];
  708.     chdir_vct[0] = stralloc(wp->cwd);
  709.     }
  710.  
  711.     wp->max = countdir(wp->dir);
  712.     if ( max == 0 || max != wp->max || strcmp(tmp, wp->cwd) != 0 ) {
  713.     wp->top = 0;
  714.     wp->pos = (-1);
  715.  
  716.     } else if ( dir != NULL ) {
  717.     seekdir(dir, 0);
  718.     while ( (np = readdir(dir)) != NULL ) {
  719.         if ( np->d_mark == FALSE )
  720.         continue;
  721.         seekdir(wp->dir, 0);
  722.         while ( (dp = readdir(wp->dir)) != NULL ) {
  723.         if ( strcmp(np->d_name, dp->d_name) == 0 ) {
  724.             dp->d_mark = TRUE;
  725.             break;
  726.         }
  727.         }
  728.     }
  729.     }
  730.  
  731.     if ( dir != NULL )
  732.     closedir(dir);
  733.  
  734.     wp->stat = FALSE;
  735.     return FALSE;
  736. }
  737. void    close_wind(int no)
  738. {
  739.     WIND *wp;
  740.  
  741.     wp = &(wind_buf[no]);
  742.  
  743.     if ( wp->dir != NULL ) {
  744.     closedir(wp->dir);
  745.     wp->dir = NULL;
  746.     }
  747.  
  748.     wp->stat = ERR;
  749. }
  750. int    get_wind(int no, int sw, int max, char *buf)
  751. {
  752.     WIND *wp;
  753.     DIRECT *dp;
  754.     char *p;
  755.     int len = 0;
  756.  
  757.     wp = &(wind_buf[no]);
  758.     if ( wp->dir == NULL )
  759.     return 0;
  760.  
  761.     if ( wp->pos >= 0 ) {
  762.     seekdir(wp->dir, wp->top + wp->pos);
  763.     if ( (dp = readdir(wp->dir)) == NULL )
  764.         return 0;
  765.     p = (sw ? path_make(wp->cwd, dp->d_name) : dp->d_name);
  766.     } else
  767.     p = wp->cwd;
  768.  
  769.     while ( len < max && *p != '\0' )
  770.     buf[len++] = *(p++);
  771.  
  772.     return len;
  773. }
  774. int    yesno(int *rc)
  775. {
  776.     int ch;
  777.  
  778.     ch = GETCH();
  779.     switch(ch) {
  780.     case K_ABORT:
  781.     case K_END_OF:
  782.     case 'N':
  783.     case 'n':
  784.     case 'ミ':
  785.     return ERR;
  786.  
  787.     case 'Y':
  788.     case 'y':
  789.     case 'ン':
  790.     return TRUE;
  791.  
  792.     case ' ':
  793.     case K_BACK_SPC:
  794.     case K_LEFT_CUR:
  795.     case K_RIGHT_CUR:
  796.     case K_UP_NODE:
  797.     case K_DOWN_NODE:
  798.     *rc = (*rc == 0 ? 1 : 0);
  799.     return FALSE;
  800.  
  801.     case K_END_LINE:
  802.     return (*rc == 0 ? TRUE : ERR);
  803.     }
  804.  
  805.     return FALSE;
  806. }
  807. int    copy_wind()
  808. {
  809.     int n, ch, rc;
  810.     int copy_type = 0;
  811.     DIRECT *dp;
  812.     char *file;
  813.     char src[128];
  814.     char dis[128];
  815.     char tmp[128];
  816.     unsigned long sz;
  817.  
  818.     if ( wind_buf[0].dir == NULL || wind_buf[1].dir == NULL ) {
  819.     message("ドライブ選択がされていません");
  820.     return ERR;
  821.     }
  822.  
  823.     seekdir(wind_buf[0].dir, 0);
  824.     while ( (dp = readdir(wind_buf[0].dir)) != NULL ) {
  825.     if ( !root_check(dp->d_name) && dp->d_mark )
  826.         break;
  827.     }
  828.  
  829.     if ( dp != NULL ) {
  830.     strcpy(src, path_make(wind_buf[0].cwd, dp->d_name));
  831.     strcat(src, "...");
  832.     copy_type |= 004;
  833. #ifdef    SELCPY
  834.     } else if ( wind_buf[0].pos >= 0 ) {
  835.     seekdir(wind_buf[0].dir, wind_buf[0].top + wind_buf[0].pos);
  836.     if ( (dp = readdir(wind_buf[0].dir)) == NULL )
  837.         return ERR;
  838.     if ( dp->d_name[0] == '.' ) {
  839.         strcpy(src, path_make(wind_buf[0].cwd, "*.*"));
  840.         copy_type |= 003;
  841.     } else {
  842.         strcpy(src, path_make(wind_buf[0].cwd, dp->d_name));
  843.         copy_type |= (IS_DIR(dp) ? 002 : 001);
  844.         file = dp->d_name;
  845.     }
  846.     } else {
  847.     strcpy(src, path_make(wind_buf[0].cwd, "*.*"));
  848.     copy_type |= 003;
  849.     }
  850. #else
  851.     } else {
  852.     message("マ-クされたファイルがありません");
  853.     return ERR;
  854.     }
  855. #endif
  856.  
  857. #ifdef    SELCPY
  858.     if ( wind_buf[1].pos >= 0 ) {
  859.     seekdir(wind_buf[1].dir, wind_buf[1].top + wind_buf[1].pos);
  860.     if ( (dp = readdir(wind_buf[1].dir)) == NULL )
  861.         return ERR;
  862.     if ( dp->d_name[0] == '.' ) {
  863.         strcpy(dis, wind_buf[1].cwd);
  864.         copy_type |= 020;
  865.     } else {
  866.         strcpy(dis, path_make(wind_buf[1].cwd, dp->d_name));
  867.         copy_type |= (IS_DIR(dp) ? 020 : 010);
  868.     }
  869.     } else {
  870.     strcpy(dis, wind_buf[1].cwd);
  871.     copy_type |= 020;
  872.     }
  873. #else
  874.     seekdir(wind_buf[1].dir, 0);
  875.     while ( (dp = readdir(wind_buf[1].dir)) != NULL ) {
  876.     if ( !root_check(dp->d_name) && dp->d_mark )
  877.         break;
  878.     }
  879.     if ( dp != NULL ) {
  880.     strcpy(dis, path_make(wind_buf[1].cwd, dp->d_name));
  881.     copy_type |= (IS_DIR(dp) ? 020 : 010);
  882.     dp->d_mark = FALSE;
  883.     } else {
  884.     strcpy(dis, wind_buf[1].cwd);
  885.     copy_type |= 020;
  886.     }
  887. #endif
  888.  
  889.     rc = 0;
  890.     for ( ; ; ) {
  891.     LOCATE(1, SCR_Y - 2);
  892.     REPCHR(' ', 77);
  893.     LOCATE(1, SCR_Y - 2);
  894.     PUTS("COPY ");
  895.     PUTS(strform(tmp, src, 26));
  896.     PUTS(" -> ");
  897.     PUTS(strform(tmp, dis, 26));
  898.     if ( rc == 0 )
  899.         PUTS(" ([Yes]/No) ? ");
  900.     else
  901.         PUTS(" (Yes/[No]) ? ");
  902.     FLUSH();
  903.  
  904.     if ( (ch = yesno(&rc)) == TRUE )
  905.         break;
  906.     else if ( ch == ERR )
  907.         return ERR;
  908.     }
  909.  
  910. #ifndef    CPIRQ
  911.     sz = 0L;
  912.     switch(copy_type) {
  913.     case 011:            /* file -> file */
  914.     case 021:            /* file -> dir */
  915.     seekdir(wind_buf[0].dir, wind_buf[0].top + wind_buf[0].pos);
  916.     if ( (dp = readdir(wind_buf[0].dir)) != NULL )
  917.         sz = dp->d_size;
  918.     break;
  919.  
  920.     case 022:            /* dir  -> dir */
  921.     rc = dir_size(src);
  922.     break;
  923.  
  924.     case 023:            /* wild -> dir */
  925.     case 024:            /* select -> dir */
  926.     seekdir(wind_buf[0].dir, 0);
  927.     while ( (dp = readdir(wind_buf[0].dir)) != NULL ) {
  928.         if ( root_check(dp->d_name) )
  929.         continue;
  930.         if ( copy_type == 024 && dp->d_mark == FALSE )
  931.         continue;
  932.         if ( IS_DIR(dp) )
  933.         sz += dir_size(strcpy(tmp,
  934.             path_make(wind_buf[0].cwd, dp->d_name)));
  935.         else
  936.         sz += dp->d_size;
  937.     }
  938.     break;
  939.     }
  940.     init_scale(sz);
  941. #endif
  942.  
  943.     rc = FALSE;
  944.     switch(copy_type) {
  945.     case 011:            /* file -> file */
  946.     rc = file_copy(src, dis);
  947.     break;
  948.  
  949.     case 012:            /* dir  -> file */
  950.     case 013:            /* wild -> file */
  951.     case 014:            /* select -> file */
  952.     message("コピ-先をディレクトリにしてください");
  953.     rc = ERR;
  954.     break;
  955.  
  956.     case 021:            /* file -> dir */
  957.     rc = file_copy(src, strcpy(tmp, path_make(dis, file)));
  958.     break;
  959.  
  960.     case 022:            /* dir  -> dir */
  961.     rc = dir_copy(src, strcpy(tmp, path_make(dis, file)));
  962.     break;
  963.  
  964.     case 023:            /* wild -> dir */
  965.     seekdir(wind_buf[0].dir, 0);
  966.     while ( (dp = readdir(wind_buf[0].dir)) != NULL ) {
  967.         if ( root_check(dp->d_name) )
  968.         continue;
  969.         strcpy(src, path_make(wind_buf[0].cwd, dp->d_name));
  970.         strcpy(tmp, path_make(dis, dp->d_name));
  971.         if ( IS_DIR(dp) ) {
  972.         if ( (rc = dir_copy(src, tmp)) )
  973.             break;
  974.         } else {
  975.         if ( (rc = file_copy(src, tmp)) )
  976.             break;
  977.         }
  978.     }
  979.     break;
  980.  
  981.     case 024:            /* select -> dir */
  982.     seekdir(wind_buf[0].dir, 0);
  983.     while ( (dp = readdir(wind_buf[0].dir)) != NULL ) {
  984.         if ( root_check(dp->d_name) || dp->d_mark == FALSE )
  985.         continue;
  986.         strcpy(src, path_make(wind_buf[0].cwd, dp->d_name));
  987.         strcpy(tmp, path_make(dis, dp->d_name));
  988.         if ( IS_DIR(dp) ) {
  989.         if ( (rc = dir_copy(src, tmp)) )
  990.             break;
  991.         } else {
  992.         if ( (rc = file_copy(src, tmp)) )
  993.             break;
  994.         }
  995.         dp->d_mark = FALSE;
  996.     }
  997.     break;
  998.     }
  999.  
  1000. #ifndef    CPIRQ
  1001.     finis_scale();
  1002. #endif
  1003.  
  1004.     return FALSE;
  1005. }
  1006. void    copy_wind_check(char *file)
  1007. {
  1008.     char *p;
  1009.     char tmp[256];
  1010.  
  1011.     strcpy(tmp, file);
  1012.     if ( (p = strrchr(tmp, '\\')) != NULL ) {
  1013.     if ( *(p - 1) == ':' )
  1014.         p++;
  1015.     *p = '\0';
  1016.     }
  1017.  
  1018.     if ( wind_buf[0].dir != NULL &&
  1019.         strcmp(tmp, wind_buf[0].cwd) == 0 ) {
  1020.     open_wind(0);
  1021.     disp_wind(0);
  1022.     }
  1023.  
  1024.     if ( wind_buf[1].dir != NULL &&
  1025.         strcmp(tmp, wind_buf[1].cwd) == 0 ) {
  1026.     open_wind(1);
  1027.     disp_wind(1);
  1028.     }
  1029. }
  1030. void    prompt(char *cwd)
  1031. {
  1032.     char *p;
  1033.  
  1034.     if ( (p = getenv("PROMPT")) == NULL )
  1035.     p = "[$p] ";
  1036.  
  1037.     while ( *p != '\0' ) {
  1038.     if ( *p == '$' ) {
  1039.         switch(*(++p)) {
  1040.         case 'E': case 'e':
  1041.         p++;
  1042.         putchar('\033');
  1043.         break;
  1044.         case 'P': case 'p':
  1045.         p++;
  1046.         fputs(cwd, stdout);
  1047.         break;
  1048.         default:
  1049.         putchar(*(p++));
  1050.         break;
  1051.         }
  1052.     } else
  1053.         putchar(*(p++));
  1054.     }
  1055.     fflush(stdout);
  1056. }
  1057. int    command(int no, char *str)
  1058. {
  1059.     int n;
  1060.     int rc;
  1061.     int len = 0;
  1062.     DIRECT *dp;
  1063.     char *p;
  1064.     char *cmd;
  1065.     char tmp[128];
  1066.  
  1067.     wind_buf[0].que = wind_buf[1].que = 0;
  1068.  
  1069. LOOP:
  1070.     rc = FALSE;
  1071.     cmd = str;
  1072.     len = 0;
  1073.     while ( *cmd != '\0' ) {
  1074.     if ( *cmd == '%' ) {
  1075.         switch(*(++cmd)) {
  1076.         case '%':
  1077.         if ( len < 127 )
  1078.             tmp[len++] = '%';
  1079.         cmd++;
  1080.         break;
  1081.  
  1082.         case '*':
  1083.         n = no;
  1084.         goto GETMARK;
  1085.         case '1':
  1086.         n = 0;
  1087.         goto GETMARK;
  1088.         case '2':
  1089.         n = 1;
  1090.         GETMARK:
  1091.         if ( wind_buf[n].dir == NULL )
  1092.             return FALSE;
  1093.         seekdir(wind_buf[n].dir, wind_buf[n].que);
  1094.         while ( (dp = readdir(wind_buf[n].dir)) != NULL ) {
  1095.             wind_buf[n].que++;
  1096.             if ( dp->d_mark )
  1097.             break;
  1098.         }
  1099.         if ( dp == NULL )
  1100.             return FALSE;
  1101.         p = path_make(wind_buf[n].cwd, dp->d_name);
  1102.         while ( len < 127 && *p != '\0' )
  1103.             tmp[len++] = *(p++);
  1104.         rc = TRUE;
  1105.         cmd++;
  1106.         break;
  1107.  
  1108.         case 'x': case 'X':
  1109.         n = no;
  1110.         goto GETCWD;
  1111.         case 's': case 'S':
  1112.         n = 0;
  1113.         goto GETCWD;
  1114.         case 'd': case 'D':
  1115.         n = 1;
  1116.         GETCWD:
  1117.         if ( wind_buf[n].dir != NULL ) {
  1118.             for ( p = wind_buf[n].cwd ; len < 127 && *p != '\0' ; )
  1119.             tmp[len++] = *(p++);
  1120.         }
  1121.         cmd++;
  1122.         break;
  1123.  
  1124.         default:
  1125.         if ( len < 127 )
  1126.             tmp[len++] = '%';
  1127.         break;
  1128.         }
  1129.  
  1130.     } else {
  1131.         if ( len < 127 )
  1132.         tmp[len++] = *cmd;
  1133.         cmd++;
  1134.     }
  1135.     }
  1136.     tmp[len] = '\0';
  1137.  
  1138.     prompt(wind_buf[1].dir == NULL ? "?" : wind_buf[no].cwd);
  1139.     printf("%s\n", tmp);
  1140.  
  1141.     if ( system(tmp) )
  1142.     return ERR;
  1143.  
  1144.     if ( rc )
  1145.     goto LOOP;
  1146.  
  1147.     return FALSE;
  1148. }
  1149. void    wait_loop()
  1150. {
  1151. }
  1152. void    wind_cur_up(int no)
  1153. {
  1154.     if ( wind_buf[no].pos == 0 && wind_buf[no].top > 0 )
  1155.     wind_buf[no].top--;
  1156.     else if ( wind_buf[no].pos < 0 ) {
  1157.     if ( wind_buf[no].max <= (SCR_Y - 8) ) {
  1158.         wind_buf[no].top = 0;
  1159.         wind_buf[no].pos = wind_buf[no].max - 1;
  1160.     } else {
  1161.         wind_buf[no].pos = (SCR_Y - 8);
  1162.         wind_buf[no].top =
  1163.         (wind_buf[no].max - 1) - wind_buf[no].pos;
  1164.     }
  1165.     } else
  1166.     wind_buf[no].pos--;
  1167. }
  1168. void    wind_cur_down(int no)
  1169. {
  1170.     if ( (wind_buf[no].top + 
  1171.         wind_buf[no].pos + 1) >= wind_buf[no].max ) {
  1172.     wind_buf[no].top = 0;
  1173.     wind_buf[no].pos = (-1);
  1174.     } else if ( wind_buf[no].pos < (SCR_Y - 8) )
  1175.     wind_buf[no].pos++;
  1176.     else
  1177.     wind_buf[no].top++;
  1178. }
  1179. void    wind_init(int no)
  1180. {
  1181.     if ( chcwdrv(wind_buf[no].drv) )
  1182.     close_wind(no);
  1183.     else {
  1184.     chcwdir(wind_buf[no].cwd);
  1185.     open_wind(no);
  1186.     }
  1187. }
  1188. void    wind_chdir(int no, char *dir)
  1189. {
  1190.     if ( dir[1] == ':' )
  1191.     wind_buf[no].drv = toupper(dir[0]) - 'A' + 1;
  1192.  
  1193.     if ( chcwdrv(wind_buf[no].drv) )
  1194.     close_wind(no);
  1195.     else {
  1196.     chcwdir(dir);
  1197.     open_wind(no);
  1198.     }
  1199. }
  1200. void    wind_command(int no, char *buf)
  1201. {
  1202.     int n;
  1203.  
  1204.     if ( buf[0] == '\0' ) {
  1205.     if ( wind_buf[no].dir == NULL ) {
  1206.         open_wind(no);
  1207.     } else if ( chcwdrv(wind_buf[no].drv) ) {
  1208.         close_wind(no);
  1209.     } else if ( chcwdir(wind_buf[no].cwd) ) {
  1210.         open_wind(no);
  1211.     } else {
  1212.         if ( wind_buf[no].pos < 0 ) {
  1213.         wind_buf[no].max = 0;
  1214.         open_wind(no);
  1215.         } else if ( exec_wind(no) )
  1216.         open_wind(no);
  1217.     }
  1218.     disp_wind(no);
  1219.  
  1220.     } else if ( buf[0] != '\0' && buf[1] == ':' &&
  1221.         buf[2] == '\0' ) {
  1222.     wind_buf[no].drv = toupper(buf[0]) - 'A' + 1;
  1223.     open_wind(no);
  1224.     disp_wind(no);
  1225.  
  1226.     } else {
  1227.     if ( wind_buf[no].dir != NULL && !chcwdrv(wind_buf[no].drv) )
  1228.         chcwdir(wind_buf[no].cwd);
  1229.  
  1230.     LOCATE(0, SCR_Y - 1);
  1231.     FLUSH();
  1232.  
  1233.     Console_Load();
  1234.     command(no, buf);
  1235.     Console_Save();
  1236.  
  1237.     REFLUSH();
  1238.     wind_buf[no].drv = _getdrive();
  1239.     open_wind(no);
  1240.     disp_wind(no);
  1241.  
  1242.     n = (no == 0 ? 1 : 0);
  1243.     if ( wind_buf[n].dir == NULL )
  1244.         open_wind(n);
  1245.     else
  1246.         wind_init(n);
  1247.     disp_wind(n);
  1248.     }
  1249. }
  1250. int    fwcp()
  1251. {
  1252.     int n, i;
  1253.     int ch;
  1254.     int no = 0;
  1255.     char buf[128 + 2];
  1256.  
  1257.     screen_init(no);
  1258.  
  1259.     wind_buf[0].drv = wind_buf[1].drv = _getdrive();
  1260.  
  1261.     open_wind(0);
  1262.     disp_wind(0);
  1263.  
  1264.     open_wind(1);
  1265.     disp_wind(1);
  1266.  
  1267.     memset(buf, 0, 128);
  1268.     strcpy(buf, VERSION);
  1269.  
  1270.     for ( ; ; ) {
  1271.     ch = input(1, SCR_Y - 2, 77, 128, no, buf);
  1272.  
  1273.     switch(ch) {
  1274.     case K_END_OF:
  1275.         if ( wind_buf[no].dir != NULL && !chcwdrv(wind_buf[no].drv) )
  1276.         chcwdir(wind_buf[no].cwd);
  1277.         return ERR;
  1278.  
  1279.     case K_WIND_CNG:
  1280.         no = (no == 0 ? 1 : 0);
  1281.         select_wind(no);
  1282.         break;
  1283.  
  1284.     case K_MARK_FILE:
  1285.         if ( !mark_wind(no, ERR) )
  1286.         disp_wind(no);
  1287.         break;
  1288.  
  1289.     case K_MARK_ALL:
  1290.         if ( !all_mark_wind(no) )
  1291.         disp_wind(no);
  1292.         break;
  1293.  
  1294.     case K_COPY_WIND:
  1295.         if ( copy_wind() )
  1296.         break;
  1297.         wind_init(0);
  1298.         disp_wind(0);
  1299.         wind_init(1);
  1300.         disp_wind(1);
  1301.         break;
  1302.  
  1303.     case K_DRV_MENU:
  1304.         SAVESCREEN();
  1305.         n = drv_menu((no == 0 ? 12 : 51), 5, wind_buf[no].drv);
  1306.         LOADSCREEN();
  1307.         FLUSH();
  1308.  
  1309.         if ( n != wind_buf[no].drv ) {
  1310.         wind_buf[no].drv = n;
  1311.         open_wind(no);
  1312.         disp_wind(no);
  1313.         }
  1314.         break;
  1315.  
  1316.     case K_DIR_MENU:
  1317.         if ( dir_menu_max <= 0 )
  1318.         break;
  1319.  
  1320.         SAVESCREEN();
  1321.         n = menu((no == 0 ? 10 : 49), 5, 0, dir_menu_vct);
  1322.         LOADSCREEN();
  1323.         FLUSH();
  1324.  
  1325.         if ( n >= 0 ) {
  1326.         wind_chdir(no, dir_menu_vct[n]);
  1327.         disp_wind(no);
  1328.         }
  1329.         break;
  1330.  
  1331.     case K_HIS_DIR:
  1332.         if ( chdir_vct[0] == NULL )
  1333.         break;
  1334.  
  1335.         SAVESCREEN();
  1336.         n = menu((no == 0 ? 8 : 47), 5, 0, chdir_vct);
  1337.         LOADSCREEN();
  1338.         FLUSH();
  1339.  
  1340.         if ( n >= 0 ) {
  1341.         wind_chdir(no, chdir_vct[n]);
  1342.         disp_wind(no);
  1343.         }
  1344.         break;
  1345.  
  1346.     case K_TREE_DIR:
  1347.         if ( chcwdrv(wind_buf[no].drv) )
  1348.         break;;
  1349.  
  1350.         SAVESCREEN();
  1351.         n = menutree((no == 0 ? 6 : 45), 5);
  1352.         LOADSCREEN();
  1353.         FLUSH();
  1354.  
  1355.         if ( !n ) {
  1356.         open_wind(no);
  1357.         disp_wind(no);
  1358.         }
  1359.         break;
  1360.  
  1361.     case K_INIT_WIND:
  1362.         wind_buf[no].max = 0;
  1363.         if ( wind_buf[no].dir == NULL )
  1364.         open_wind(no);
  1365.         else
  1366.         wind_init(no);
  1367.         disp_wind(no);
  1368.         break;
  1369.  
  1370.     case K_END_LINE:
  1371.         wind_command(no, buf);
  1372.         break;
  1373.  
  1374.     case K_UP_NODE:
  1375.         if ( wind_buf[no].dir != NULL ) {
  1376.             wind_cur_up(no);
  1377.             update_wind(no);
  1378.         }
  1379.         break;
  1380.  
  1381.     case K_DOWN_NODE:
  1382.         if ( wind_buf[no].dir != NULL ) {
  1383.             wind_cur_down(no);
  1384.             update_wind(no);
  1385.         }
  1386.         break;
  1387.  
  1388.     case K_UP_MARK:
  1389.         if ( wind_buf[no].dir != NULL ) {
  1390.             wind_cur_up(no);
  1391.         mark_wind(no, FALSE);
  1392.             update_wind(no);
  1393.         }
  1394.         break;
  1395.  
  1396.     case K_DOWN_MARK:
  1397.         if ( wind_buf[no].dir != NULL ) {
  1398.         mark_wind(no, TRUE);
  1399.             wind_cur_down(no);
  1400.             update_wind(no);
  1401.         }
  1402.         break;
  1403.  
  1404.     case K_SKIP_DOC:
  1405.         if ( !skip_wind(no) )
  1406.         disp_wind(no);
  1407.         break;
  1408.  
  1409.     case K_SCREEN_FLUSH:
  1410.         REFLUSH();
  1411.         FLUSH();
  1412.         break;
  1413.  
  1414.     case K_CONSOLE:
  1415.         Console_Load();
  1416.         GETCH();
  1417.         REFLUSH();
  1418.         FLUSH();
  1419.         break;
  1420.  
  1421.     case K_SORT_MODE:
  1422.         if ( ++wind_buf[no].mode > 3 )
  1423.         wind_buf[no].mode = 0;
  1424.         wind_init(no);
  1425.         disp_wind(no);
  1426.         break;
  1427.  
  1428.     case K_HELP:
  1429.         SAVESCREEN();
  1430.         CLS();
  1431.         key_map();
  1432.         FLUSH();
  1433.         GETCH();
  1434.         LOADSCREEN();
  1435.         FLUSH();
  1436.         break;
  1437.     }
  1438.     }
  1439.  
  1440.     return ERR;
  1441. }
  1442.  
  1443. static    void    file_defs(FILE *fp, char *tmp)
  1444. {
  1445.     char *p;
  1446.  
  1447.     while ( fgets(tmp, LINSIZ, fp) != NULL ) {
  1448.     if ( (p = strchr(tmp, '\n')) != NULL )
  1449.         *p = '\0';
  1450.     if ( strcmp(tmp, "#end") == 0 )
  1451.         break;
  1452.     if ( (p = strchr(tmp, '=')) == NULL )
  1453.         continue;
  1454.     *(p++) = '\0';
  1455.     while ( isspace(*p) )
  1456.         p++;
  1457.     if ( *p == '\0' )
  1458.         continue;
  1459.  
  1460.     if ( strcmp(tmp, "TERMCAP") == 0 )
  1461.         termcap_file = strdup(p);
  1462.     else if ( strcmp(tmp, "TERM") == 0 )
  1463.         term_name = strdup(p);
  1464.     }
  1465. }
  1466. static    void    chdir_defs(FILE *fp, char *tmp)
  1467. {
  1468.     char *p;
  1469.  
  1470.     while ( fgets(tmp, LINSIZ, fp) != NULL ) {
  1471.     if ( (p = strchr(tmp, '\n')) != NULL )
  1472.         *p = '\0';
  1473.     if ( strcmp(tmp, "#end") == 0 )
  1474.         break;
  1475.     if ( tmp[0] == '\0' )
  1476.         continue;
  1477.  
  1478.     dir_menu_vct[dir_menu_max++] = strdup(tmp);
  1479.  
  1480.         if ( dir_menu_max >= dir_menu_ent ) {
  1481.             dir_menu_ent += 8;
  1482.             if ( (dir_menu_vct = (char **)realloc(dir_menu_vct,
  1483.             sizeof(char *) * dir_menu_ent)) == NULL ) {
  1484.         fprintf(stderr, "chdir menu malloc error\n");
  1485.                 exit(1);
  1486.         }
  1487.         }
  1488.  
  1489.     dir_menu_vct[dir_menu_max] = NULL;
  1490.     }
  1491. }
  1492. int    config(char *file)
  1493. {
  1494.     FILE *fp;
  1495.     char *p;
  1496.     char tmp[LINSIZ + 2];
  1497.  
  1498.     if ( (fp = fopen(file,"r")) == NULL )
  1499.     return ERR;
  1500.  
  1501.     while ( fgets(tmp, LINSIZ, fp) != NULL ) {
  1502.     if ( (p = strchr(tmp, '\n')) != NULL )
  1503.         *p = '\0';
  1504.     if ( strcmp(tmp, "#keydef") == 0 )
  1505.         key_defs(fp, tmp);
  1506.     else if ( strcmp(tmp, "#filedef") == 0 )
  1507.         file_defs(fp, tmp);
  1508.     else if ( strcmp(tmp, "#chdir") == 0 )
  1509.         chdir_defs(fp, tmp);
  1510.     }
  1511.  
  1512.     fclose(fp);
  1513.  
  1514.     return FALSE;
  1515. }
  1516. void _interrupt _cdecl _far abort_handler(
  1517.     unsigned _es,    unsigned _ds,
  1518.     unsigned _di,    unsigned _si,
  1519.     unsigned _bp,    unsigned _sp,
  1520.     unsigned _bx,    unsigned _dx,
  1521.     unsigned _cx,    unsigned _ax,
  1522.     unsigned _ip,    unsigned _cs,
  1523.     unsigned _flag)
  1524. {
  1525.  _asm {
  1526.     mov ax,_ax
  1527.     mov al,03h
  1528.     mov _ax,ax
  1529.  }
  1530. }
  1531. int    main(int ac, char *av[])
  1532. {
  1533.     char *p;
  1534.     char tmp[128];
  1535.  
  1536.     dir_menu_ent = 8;
  1537.     dir_menu_vct = (char **)malloc(sizeof(char *) * 8);
  1538.  
  1539.     if ( config("fwcp.def") ) {
  1540.     if ( (p = getenv("FWCP")) == NULL || config(p) ) {
  1541.         strcpy(tmp, av[0]);
  1542.         if ( (p = strrchr(tmp, '\\')) != NULL ||
  1543.          (p = strrchr(tmp, ':')) != NULL ) {
  1544.         strcpy(p + 1, "fwcp.def");
  1545.         if ( config(tmp) )
  1546.             config(config_file);
  1547.         } else
  1548.         config(config_file);
  1549.     }
  1550.     }
  1551.  
  1552.     DSKINIT();
  1553.  
  1554.     Console_Save();
  1555.     if ( SCRNINIT(term_name) ) {
  1556.     fprintf(stderr, "Screen init error");
  1557.     exit(1);
  1558.     }
  1559.  
  1560.     KEYINIT();
  1561.  
  1562.     _dos_setvect(0x24, abort_handler);
  1563.  
  1564.     while ( !fwcp() )
  1565.     ;
  1566.  
  1567.     SCRNEND();
  1568.     KEYEND();
  1569.     Console_Load();
  1570.  
  1571.     return 0;
  1572. }
  1573.